home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / MSJV7_2B.ARJ / FILE.C < prev    next >
C/C++ Source or Header  |  1992-03-01  |  14KB  |  533 lines

  1. /*
  2.   OLE SERVER DEMO                                                                        
  3.   File.c                    
  4.                                                                          
  5.   This file contains file input/output functions for for the OLE server demo.
  6.                                                                          
  7.   (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved        
  8. */
  9.  
  10.  
  11.  
  12. #include <Windows.h>
  13. #include <CommDlg.h>
  14. #include "Ole.h"
  15. #include "SrvrDemo.h"
  16.  
  17. // File signature stored in the file.
  18. #define szSignature "ServerDemo"
  19. #define cchSigLen (10+1)
  20.  
  21. // Delimiter for fields in the file
  22. #define chDelim ':'
  23.  
  24. // Default file extension
  25. #define szDefExt "Sd"
  26.  
  27. // File header structure
  28. typedef struct
  29. {
  30.    char szSig [cchSigLen];
  31.    char chDelim1;
  32.    VERSION version;
  33.    char chDelim2;
  34.    char rgfObjNums [cfObjNums+1];
  35. } HEADER;
  36.  
  37. static BOOL  GetFileOpenFilename (LPSTR lpszFilename);
  38. static BOOL  GetFileSaveFilename (LPSTR lpszFilename);
  39. static void  InitOfn (OPENFILENAME *pofn);
  40. static BOOL  SaveDocIntoFile (PSTR);
  41. static LPOBJ ReadObj (int fh);
  42.  
  43.  
  44.  
  45. /* CreateDocFromFile
  46.  * -----------------
  47.  *
  48.  * Read a document from the specified file.
  49.  *
  50.  * LPSTR lpszDoc     - Name of the file containing the document
  51.  * LHSERVERDOC lhdoc - Handle to the document
  52.  * DOCTYPE doctype   - In what state the document is created
  53.  * 
  54.  * RETURNS: TRUE if successful, FALSE otherwise
  55.  *
  56.  * CUSTOMIZATION: Re-implement
  57.  *                This function will need to be completely re-implemented
  58.  *                to support your application's file format.
  59.  *
  60.  */
  61. BOOL CreateDocFromFile (LPSTR lpszDoc, LHSERVERDOC lhdoc, DOCTYPE doctype)
  62. {
  63.     int     fh;        // File handle
  64.     HEADER  hdr;
  65.     int     i;
  66.  
  67.     if ((fh =_lopen (lpszDoc, OF_READ)) == -1)
  68.         return FALSE;
  69.  
  70.     // Read header from file.
  71.     if (_lread (fh, (LPSTR) &hdr, sizeof (HEADER)) < sizeof (HEADER))
  72.       goto Error;
  73.  
  74.     // Check to see if file is a server demo file.
  75.     if (lstrcmp(hdr.szSig, szSignature))
  76.       goto Error;
  77.  
  78.     if (hdr.chDelim1 != chDelim)
  79.       goto Error;
  80.  
  81.     // Check to see if file was saved under the most recent version.
  82.     // Here is where you would handle reading in old versions.
  83.     if (hdr.version != version)
  84.       goto Error;
  85.  
  86.     if (hdr.chDelim2 != chDelim)
  87.       goto Error;
  88.  
  89.     if (!CreateNewDoc (lhdoc, lpszDoc, doctype))
  90.       goto Error;
  91.  
  92.     // Get the array indicating which object numbers have been used.
  93.     for (i=1; i <= cfObjNums; i++)
  94.       docMain.rgfObjNums[i] = hdr.rgfObjNums[i];
  95.  
  96.     // Read in object data.
  97.     for (i=0; ReadObj (fh); i++);
  98.  
  99.     if (!i)    
  100.     {
  101.          OLESTATUS olestatus;
  102.  
  103.          fRevokeSrvrOnSrvrRelease = FALSE;
  104.  
  105.          if ((olestatus = RevokeDoc()) > OLE_WAIT_FOR_RELEASE)
  106.             goto Error;
  107.          else if (olestatus == OLE_WAIT_FOR_RELEASE)
  108.             Wait (&fWaitingForDocRelease);
  109.  
  110.          fRevokeSrvrOnSrvrRelease = TRUE;
  111.          EmbeddingModeOff();
  112.          goto Error;
  113.     }  
  114.  
  115.     _lclose (fh);
  116.  
  117.     fDocChanged = FALSE;
  118.     return TRUE;
  119.  
  120. Error:
  121.     _lclose (fh);
  122.     return FALSE;
  123.  
  124. }
  125.  
  126.  
  127.  
  128. /* OpenDoc
  129.  * -------
  130.  *
  131.  * Prompt the user for which document he wants to open
  132.  *
  133.  * RETURNS: TRUE if successful, FALSE otherwise.
  134.  *
  135.  * CUSTOMIZATION: None, except your application may or may not call 
  136.  *                CreateNewObj to create a default object.
  137.  *
  138.  */
  139. BOOL OpenDoc (void)
  140. {
  141.    char        szDoc[cchFilenameMax];
  142.    BOOL        fUpdateLater;
  143.    OLESTATUS   olestatus;
  144.  
  145.    if (SaveChangesOption (&fUpdateLater) == IDCANCEL)
  146.       return FALSE;
  147.  
  148.    if (!GetFileOpenFilename (szDoc))
  149.    {
  150.       if (fUpdateLater)
  151.       {
  152.          // The user chose the "Yes, Update" button but the 
  153.          // File Open dialog box failed for some reason 
  154.          // (perhaps the user chose Cancel).
  155.          // Even though the user chose "Yes, Update", there is no way
  156.          // to update a client that does not accept updates
  157.          // except when the document is closed.
  158.       }
  159.       return FALSE;
  160.    }
  161.  
  162.    if (fUpdateLater)
  163.    {
  164.       // The non-standard OLE client did not accept the update when 
  165.       // we requested it, so we are sending the client OLE_CLOSED now that
  166.       // we are closing the document.
  167.       SendDocMsg (OLE_CLOSED);
  168.    }
  169.  
  170.    fRevokeSrvrOnSrvrRelease = FALSE;
  171.  
  172.    if ((olestatus = RevokeDoc()) > OLE_WAIT_FOR_RELEASE)
  173.       return FALSE;
  174.    else if (olestatus == OLE_WAIT_FOR_RELEASE)
  175.       Wait (&fWaitingForDocRelease);
  176.  
  177.    fRevokeSrvrOnSrvrRelease = TRUE;
  178.    EmbeddingModeOff();
  179.  
  180.    if (!CreateDocFromFile (szDoc, NULL, doctypeFromFile))
  181.    {
  182.       MessageBox (hwndMain,
  183.                   "Reading from file failed.\r\nFile may not be in proper file format.",
  184.                   szAppName,
  185.                   MB_ICONEXCLAMATION | MB_OK);
  186.       // We already revoked the document, so give the user a new one to edit.
  187.       CreateNewDoc (NULL, "(Untitled)", doctypeNew);
  188.       CreateNewObj (FALSE);
  189.       return FALSE;
  190.    }
  191.    fDocChanged = FALSE;
  192.    return TRUE;
  193. }
  194.  
  195.  
  196.  
  197. /* ReadObj
  198.  * --------
  199.  *
  200.  * Read the next object from a file, allocate memory for it, and return
  201.  * a pointer to it.
  202.  *
  203.  * int fh - File handle
  204.  * 
  205.  * RETURNS: A pointer to the object
  206.  * 
  207.  * CUSTOMIZATION: Server Demo specific
  208.  *
  209.  */
  210. static LPOBJ ReadObj (int fh)
  211. {
  212.     HANDLE hObj = NULL;
  213.     LPOBJ   lpobj = NULL;
  214.  
  215.     hObj = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (OBJ));
  216.  
  217.     if (hObj == NULL)
  218.       return NULL;
  219.  
  220.     lpobj = (LPOBJ) LocalLock (hObj);
  221.  
  222.     if (lpobj==NULL)
  223.     {
  224.       LocalFree (hObj);
  225.       return NULL;
  226.     }
  227.  
  228.     if (_lread(fh, (LPSTR) &lpobj->native, sizeof(NATIVE)) < sizeof (NATIVE))
  229.     {
  230.         LocalUnlock (hObj);
  231.         LocalFree (hObj);
  232.         return NULL;
  233.     }
  234.  
  235.     lpobj->hObj             = hObj;
  236.     lpobj->oleobject.lpvtbl = &objvtbl;
  237.     lpobj->aName            = GlobalAddAtom (lpobj->native.szName);
  238.  
  239.     if (!CreateWindow(
  240.         "ObjClass",
  241.         "Obj",
  242.         WS_THICKFRAME | WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE ,
  243.         lpobj->native.nX,
  244.         lpobj->native.nY,
  245.         lpobj->native.nWidth,
  246.         lpobj->native.nHeight,
  247.         hwndMain,
  248.         NULL,
  249.         hInst,
  250.         (LPSTR) lpobj ))
  251.     {
  252.         LocalUnlock (hObj);
  253.         LocalFree (hObj);
  254.         return NULL;
  255.     }
  256.  
  257.     return lpobj;
  258. }
  259.  
  260.  
  261.  
  262. /* SaveDoc
  263.  * -------
  264.  *
  265.  * Save the document.
  266.  *
  267.  * CUSTOMIZATION: None
  268.  *
  269.  */
  270.  
  271. BOOL SaveDoc (void)
  272. {
  273.     if (docMain.doctype == doctypeNew)
  274.         return SaveDocAs();
  275.     else
  276.     {
  277.         char     szDoc [cchFilenameMax];
  278.  
  279.         GlobalGetAtomName (docMain.aName, szDoc, cchFilenameMax);
  280.         return SaveDocIntoFile(szDoc);
  281.     }
  282. }
  283.  
  284.  
  285.  
  286. /* SaveDocAs
  287.  * ---------
  288.  *
  289.  * Prompt the user for a filename, and save the document under that filename.
  290.  *
  291.  * RETURNS: TRUE if successful or user chose CANCEL
  292.  *          FALSE if SaveDocIntoFile fails
  293.  *
  294.  * CUSTOMIZATION: None
  295.  *
  296.  */
  297. BOOL SaveDocAs (void)
  298. {
  299.    char szDoc[cchFilenameMax];
  300.    char szDocOld[cchFilenameMax];
  301.    BOOL fUpdateLater = FALSE;
  302.  
  303.    // If document is embedded, give user a chance to update.
  304.    // Save old document name in case the save fails.
  305.    if (!GlobalGetAtomName (docMain.aName, szDocOld, cchFilenameMax))
  306.       ErrorBox ("Fatal Error: Document name is invalid.");
  307.  
  308.    if (GetFileSaveFilename (szDoc)) 
  309.    {
  310.  
  311.       if (docMain.doctype == doctypeEmbedded)
  312.          return SaveDocIntoFile(szDoc);
  313.  
  314.       if (fUpdateLater)
  315.       {
  316.          // The non-standard OLE client did not accept the update when 
  317.          // we requested it, so we are sending the client OLE_CLOSED now that
  318.          // we are closing the document.
  319.          SendDocMsg (OLE_CLOSED);
  320.       }
  321.  
  322.       // Set the window title bar.
  323.       SetTitle (szDoc, FALSE);
  324.       OleRenameServerDoc(docMain.lhdoc, szDoc);
  325.  
  326.       if (SaveDocIntoFile(szDoc))
  327.          return TRUE;
  328.       else
  329.       {  // Restore old name
  330.          SetTitle (szDocOld, FALSE);
  331.          OleRenameServerDoc(docMain.lhdoc, szDocOld); 
  332.          return FALSE;
  333.       }
  334.    }
  335.    else  // user chose Cancel
  336.       return FALSE;
  337.          // The user chose the "Yes, Update" button but the 
  338.          // File Open dialog box failed for some reason 
  339.          // (perhaps the user chose Cancel).
  340.          // Even though the user chose "Yes, Update", there is no way
  341.          // to update a non-standard OLE client that does not accept updates
  342.          // except when the document is closed.
  343. }
  344.  
  345.  
  346.  
  347. /* SaveDocIntoFile
  348.  * ---------------
  349.  *
  350.  * Save the document into a file whose name is determined from docMain.aName.
  351.  *
  352.  * RETURNS: TRUE if successful
  353.  *          FALSE otherwise
  354.  *
  355.  * CUSTOMIZATION: Re-implement
  356.  *
  357.  */
  358. static BOOL SaveDocIntoFile (PSTR pDoc)
  359. {
  360.     HWND     hwnd;
  361.     int      fh;    // File handle
  362.     LPOBJ    lpobj;
  363.     HEADER   hdr;
  364.     int      i;
  365.  
  366.     hwnd = GetWindow (hwndMain, GW_CHILD);
  367.  
  368.     if (!hwnd)
  369.     {
  370.         ErrorBox ("Could not save NULL file.");
  371.         return FALSE;
  372.     }
  373.    
  374.     // Get document name.
  375.     if ((fh =_lcreat (pDoc, 0)) == -1)
  376.     {
  377.         ErrorBox ("Could not save file.");
  378.         return FALSE;
  379.     }
  380.  
  381.     // Fill in header.
  382.     lstrcpy (hdr.szSig, szSignature);
  383.     hdr.chDelim1 = chDelim;
  384.     hdr.version  = version;
  385.     hdr.chDelim2 = chDelim;
  386.     for (i=1; i <= cfObjNums; i++)
  387.       hdr.rgfObjNums[i] = docMain.rgfObjNums[i];
  388.  
  389.     // Write header to file.
  390.     if (_lwrite (fh, (LPSTR) &hdr, sizeof (HEADER)) < sizeof(HEADER))
  391.          goto Error; // Error writing file header
  392.  
  393.     // Write each object's native data.
  394.     while (hwnd) 
  395.     {
  396.       lpobj = (LPOBJ) GetWindowLong (hwnd, ibLpobj);
  397.       if (_lwrite (fh, (LPSTR)&lpobj->native, sizeof (NATIVE)) 
  398.           < sizeof(NATIVE))
  399.          goto Error; // Error writing file header
  400.  
  401.       hwnd = GetWindow (hwnd, GW_HWNDNEXT);
  402.     }
  403.     _lclose (fh);
  404.  
  405.  
  406.     if (docMain.doctype != doctypeEmbedded)
  407.     {
  408.          docMain.doctype = doctypeFromFile;
  409.          OleSavedServerDoc(docMain.lhdoc);
  410.          fDocChanged = FALSE;
  411.     }  
  412.  
  413.     return TRUE;
  414.  
  415. Error:
  416.       _lclose (fh);
  417.       ErrorBox ("Could not save file.");
  418.       return FALSE;
  419.  
  420. }
  421.  
  422.  
  423.  
  424. /* Common Dialog functions */
  425.  
  426.  
  427. /* InitOfn
  428.  * -------
  429.  *
  430.  * Initialize an OPENFILENAME structure with default values.
  431.  * OPENFILENAME is defined in CommDlg.h.
  432.  *
  433.  * 
  434.  * CUSTOMIZATION: Change lpstrFilter.  You may also customize the common 
  435.  *                dialog box if you wish.  (See the Windows SDK documentation.)
  436.  *
  437.  */
  438. static void InitOfn (OPENFILENAME *pofn)
  439. {
  440.    // GetOpenFileName or GetSaveFileName will put the 8.3 filename into 
  441.    // szFileTitle[].
  442.    // SrvrDemo does not use this filename, but rather uses the fully qualified 
  443.    // pathname in pofn->lpstrFile[].
  444.    static char szFileTitle[13]; 
  445.  
  446.    pofn->Flags          = 0;
  447.    pofn->hInstance      = hInst;
  448.    pofn->hwndOwner      = hwndMain;
  449.    pofn->lCustData      = NULL;
  450.    pofn->lpfnHook       = NULL;
  451.    pofn->lpstrCustomFilter = NULL;
  452.    pofn->lpstrDefExt    = szDefExt;
  453.    // lpstrFile[] is the initial filespec that appears in the edit control. 
  454.    // Must be set to non-NULL before calling the common dialog box function.
  455.    // On return, lpstrFile[] will contain the fully-qualified pathname 
  456.    // corresponding to the file the user chose.
  457.    pofn->lpstrFile      = NULL;    
  458.    pofn->lpstrFilter    = "Server Demo (*." szDefExt ")\0*." szDefExt "\0" ;
  459.    // lpstrFileTitle[] will contain the user's chosen filename without a path.
  460.    pofn->lpstrFileTitle = szFileTitle;
  461.    pofn->lpstrInitialDir= NULL;
  462.    // Title Bar.  NULL means use default title.
  463.    pofn->lpstrTitle     = NULL;    
  464.    pofn->lpTemplateName = NULL;
  465.    pofn->lStructSize    = sizeof (OPENFILENAME);
  466.    pofn->nFilterIndex   = 1L;
  467.    pofn->nFileOffset    = 0;
  468.    pofn->nFileExtension = 0;
  469.    pofn->nMaxFile       = cchFilenameMax;
  470.    pofn->nMaxCustFilter = 0L;
  471. }
  472.  
  473.  
  474.  
  475.  
  476. /* GetFileOpenFilename
  477.  * -------------------
  478.  *
  479.  * Call the common dialog box function GetOpenFileName to get a file name
  480.  * from the user when the user chooses the "File Open" menu item.
  481.  *
  482.  * LPSTR lpszFilename - will contain the fully-qualified pathname on exit.
  483.  *
  484.  * RETURNS: TRUE if successful, FALSE otherwise.
  485.  * 
  486.  * CUSTOMIZATION: None
  487.  *
  488.  */
  489. static BOOL GetFileOpenFilename (LPSTR lpszFilename)
  490. {
  491.    OPENFILENAME ofn;
  492.    InitOfn (&ofn);
  493.    ofn.Flags |= OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  494.    // Create initial filespec.
  495.    wsprintf (lpszFilename, "*.%s", (LPSTR) szDefExt);
  496.    // Have the common dialog function return the filename in lpszFilename.
  497.    ofn.lpstrFile = lpszFilename;
  498.    if (!GetOpenFileName (&ofn))
  499.       return FALSE;
  500.    return TRUE;
  501. }
  502.  
  503.  
  504.  
  505. /* GetFileSaveFilename
  506.  * -------------------
  507.  *
  508.  * Call the common dialog box function GetSaveFileName to get a file name
  509.  * from the user when the user chooses the "File Save As" menu item, or the
  510.  * "File Save" menu item for an unnamed document.
  511.  *
  512.  * LPSTR lpszFilename - will contain the fully-qualified pathname on exit.
  513.  *
  514.  * RETURNS: TRUE if successful, FALSE otherwise.
  515.  * 
  516.  * CUSTOMIZATION: None
  517.  *
  518.  */
  519. static BOOL GetFileSaveFilename (LPSTR lpszFilename)
  520. {
  521.    OPENFILENAME ofn;
  522.    InitOfn (&ofn);
  523.    ofn.Flags |= OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
  524.    // Create initial filespec.
  525.    wsprintf (lpszFilename, "*.%s", (LPSTR) szDefExt);
  526.    // Have the common dialog function return the filename in lpszFilename.
  527.    ofn.lpstrFile = lpszFilename;
  528.    if (!GetSaveFileName (&ofn))
  529.       return FALSE;
  530.    return TRUE;
  531. }
  532.  
  533.